﻿using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;

namespace ManagedSandbox
{
    public partial class SecurityPermissionForm : Form, IPermissionEditor
    {
        public IPermission Permission { get; private set; }

        public SecurityPermissionForm()
        {
            InitializeComponent();
        }

        public void Initialize(IPermission permission)
        {
            Permission = permission;

            var securityPermission = Permission as SecurityPermission;

            if (null != securityPermission)
            {
                if (securityPermission.IsUnrestricted())
                {
                    unrestrictedCheckBox.Checked = true;
                    permissionPanel.Enabled = false;
                }
                else
                {
                    if (0 != (SecurityPermissionFlag.Assertion & securityPermission.Flags))
                        assertionCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.UnmanagedCode & securityPermission.Flags))
                        unmanagedCodeCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.SkipVerification & securityPermission.Flags))
                        skipVerificationCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.Execution & securityPermission.Flags))
                        executionCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlThread & securityPermission.Flags))
                        controlThreadCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlEvidence & securityPermission.Flags))
                        controlEvidenceCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlPolicy & securityPermission.Flags))
                        controlPolicyCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.SerializationFormatter & securityPermission.Flags))
                        serializationFormatterCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlDomainPolicy & securityPermission.Flags))
                        controlDomainPolicyCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlPrincipal & securityPermission.Flags))
                        controlPrincipalCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.ControlAppDomain & securityPermission.Flags))
                        controlAppDomainCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.RemotingConfiguration & securityPermission.Flags))
                        remotingConfigurationCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.Infrastructure & securityPermission.Flags))
                        infrastructureCheckBox.Checked = true;

                    if (0 != (SecurityPermissionFlag.BindingRedirects & securityPermission.Flags))
                        bindingRedirectsCheckBox.Checked = true;
                }
            }
        }

        public CheckState GetCheckState()
        {
            var securityPermission = Permission as SecurityPermission;

            if (null == securityPermission)
                return CheckState.Unchecked;

            if (securityPermission.IsUnrestricted())
                return CheckState.Checked;

            return (0 == (SecurityPermissionFlag.AllFlags & securityPermission.Flags)) ?
                CheckState.Unchecked : CheckState.Indeterminate;
        }

        private void unrestrictedCheckBoxCheckedChanged(object sender, System.EventArgs e)
        {
            permissionPanel.Enabled = !unrestrictedCheckBox.Checked;
        }

        private void okButtonClick(object sender, System.EventArgs e)
        {
            if (unrestrictedCheckBox.Checked)
                Permission = new SecurityPermission(PermissionState.Unrestricted);
            else
            {
                var securityPermissionFlag = SecurityPermissionFlag.NoFlags;

                if (assertionCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.Assertion;

                if (unmanagedCodeCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.UnmanagedCode;

                if (skipVerificationCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.SkipVerification;

                if (executionCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.Execution;

                if (controlThreadCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlThread;

                if (controlEvidenceCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlEvidence;

                if (controlPolicyCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlPolicy;

                if (serializationFormatterCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.SerializationFormatter;

                if (controlDomainPolicyCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlDomainPolicy;

                if (controlPrincipalCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlPrincipal;

                if (controlAppDomainCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.ControlAppDomain;

                if (remotingConfigurationCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.RemotingConfiguration;

                if (infrastructureCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.Infrastructure;

                if (bindingRedirectsCheckBox.Checked)
                    securityPermissionFlag |= SecurityPermissionFlag.BindingRedirects;

                Permission = 0 == (SecurityPermissionFlag.AllFlags & securityPermissionFlag)
                                 ? null
                                 : new SecurityPermission(securityPermissionFlag);
            }

            DialogResult = DialogResult.OK;
        }
    }
}
